package ar.com.gep.soccer.utils.generator;

import java.util.ArrayList;
import java.util.List;

import ar.com.gep.soccer.services.dto.GameDTO;
import ar.com.gep.soccer.services.dto.RoundDTO;
import ar.com.gep.soccer.services.dto.TeamDTO;

/**
 * 
 * @author guillermo
 * 
 */
public class FixtureGenerator {

	private static GameDTO getGame(TeamDTO t1, TeamDTO t2) {
		GameDTO game = new GameDTO();
		game.setHome(t1);
		game.setAway(t2);
		return game;
	}

	private static List<GameDTO> getGamees(TeamDTO... teams) {
		List<GameDTO> Gamees = new ArrayList<GameDTO>();
		for (int i = 0; i < teams.length; i += 2) {
			Gamees.add(getGame(teams[i], teams[i + 1]));
		}
		return Gamees;
	}

	private static RoundDTO getRound(List<GameDTO> Gamees) {
		RoundDTO round = new RoundDTO();
		round.setGames(Gamees);
		return round;
	}

	private static List<RoundDTO> getGameesHalf4(TeamDTO t1, TeamDTO t2, TeamDTO t3, TeamDTO t4) {
		List<RoundDTO> rounds = new ArrayList<RoundDTO>();
		rounds.add(getRound(getGamees(t1, t2, t3, t4)));
		rounds.add(getRound(getGamees(t2, t4, t3, t1)));
		rounds.add(getRound(getGamees(t1, t4, t2, t3)));
		return rounds;
	}

	private static List<RoundDTO> generateGamees4(List<TeamDTO> teams, Boolean half) {
		List<RoundDTO> rounds = new ArrayList<RoundDTO>();
		rounds.addAll(getGameesHalf4(teams.get(0), teams.get(1), teams.get(2), teams.get(3)));
		if (half) {
			rounds.addAll(getGameesHalf4(teams.get(1), teams.get(0), teams.get(3), teams.get(2)));
		}
		return rounds;
	}

	private static void generateGameesHalf8(List<RoundDTO> rounds, TeamDTO... teams) {
		RoundDTO round = getRound(getGamees(teams[0], teams[1], teams[2], teams[3]));
		round.getGames().addAll(getGamees(teams[4], teams[5], teams[6], teams[7]));
		rounds.add(round);
	}

	private static List<RoundDTO> getGameesHalf8(List<TeamDTO> teams, final Boolean half) {
		List<RoundDTO> firstHalf = new ArrayList<RoundDTO>();
		List<RoundDTO> secondHalf = new ArrayList<RoundDTO>();

		generateGameesHalf8(firstHalf, teams.get(0), teams.get(1), teams.get(2), teams.get(3), teams.get(4), teams.get(5), teams.get(6), teams.get(7));
		generateGameesHalf8(firstHalf, teams.get(0), teams.get(2), teams.get(1), teams.get(3), teams.get(4), teams.get(6), teams.get(5), teams.get(7));
		generateGameesHalf8(firstHalf, teams.get(3), teams.get(0), teams.get(1), teams.get(2), teams.get(7), teams.get(4), teams.get(5), teams.get(6));
		generateGameesHalf8(firstHalf, teams.get(0), teams.get(4), teams.get(1), teams.get(5), teams.get(2), teams.get(6), teams.get(3), teams.get(7));
		generateGameesHalf8(firstHalf, teams.get(5), teams.get(0), teams.get(4), teams.get(1), teams.get(7), teams.get(2), teams.get(6), teams.get(3));
		generateGameesHalf8(firstHalf, teams.get(0), teams.get(6), teams.get(1), teams.get(7), teams.get(2), teams.get(4), teams.get(3), teams.get(5));
		generateGameesHalf8(firstHalf, teams.get(7), teams.get(0), teams.get(6), teams.get(1), teams.get(5), teams.get(2), teams.get(4), teams.get(3));
		if (half) {
			generateGameesHalf8(secondHalf, teams.get(1), teams.get(0), teams.get(3), teams.get(2), teams.get(5), teams.get(4), teams.get(7), teams.get(6));
			generateGameesHalf8(secondHalf, teams.get(2), teams.get(0), teams.get(3), teams.get(1), teams.get(6), teams.get(4), teams.get(7), teams.get(5));
			generateGameesHalf8(secondHalf, teams.get(0), teams.get(3), teams.get(2), teams.get(1), teams.get(4), teams.get(7), teams.get(6), teams.get(5));
			generateGameesHalf8(secondHalf, teams.get(4), teams.get(0), teams.get(5), teams.get(1), teams.get(6), teams.get(2), teams.get(7), teams.get(3));
			generateGameesHalf8(secondHalf, teams.get(0), teams.get(5), teams.get(1), teams.get(4), teams.get(2), teams.get(7), teams.get(3), teams.get(6));
			generateGameesHalf8(secondHalf, teams.get(6), teams.get(0), teams.get(7), teams.get(1), teams.get(4), teams.get(2), teams.get(5), teams.get(3));
			generateGameesHalf8(secondHalf, teams.get(0), teams.get(7), teams.get(1), teams.get(6), teams.get(2), teams.get(5), teams.get(3), teams.get(4));
			firstHalf.addAll(secondHalf);
		}
		return firstHalf;
	}

	private static List<RoundDTO> generateGamees8(List<TeamDTO> teams, Boolean half) {
		List<RoundDTO> rounds = new ArrayList<RoundDTO>();
		rounds.addAll(getGameesHalf8(teams, half));
		return rounds;
	}

	public static List<RoundDTO> generateGamees(List<TeamDTO> teams, Boolean half) {
		switch (teams.size()) {
		case 4:
			return FixtureGenerator.generateGamees4(teams, half);
		case 8:
			return FixtureGenerator.generateGamees8(teams, half);
		default:
			break;
		}

		return null;
	}

}
